#ifndef __UTIL__
#define __UTIL__

#include <stdint.h>
#include <pthread.h>

/*
 * Error Handling/Reporting API
 * 
 * I am pleased with the error handling/reporting
 * from my ohmdns project, so I'm pulling it into this
 * for use. I can't stand having no builtin error
 * reporting, so this attempts to bridge the gap with
 * an inbuilt library that abstracts the error/log output
 */

typedef struct Error Error;
typedef struct ErrorMonitor ErrorMonitor;

/*
 * Error API settings constants.
 */
enum
{
	BACKTRACE_COUNT		= 100,
	ERR_STRLEN		= 150,
};

struct Error
{
	char		estr[ERR_STRLEN];
	uint16_t	eid;

	/* Backtrace Fields */
	int		bt_nptrs;
	char**	       	bt_estrs;
	void*		bt_buffer[BACKTRACE_COUNT];
};

struct ErrorMonitor
{
	int		efd;	// Output file descriptor
};

extern void	_error(Error* err, int (*efunc)(Error* err), char* estr, ...);
extern void	_warn(const char* fnstr, char* wstr, ...);
extern int	error_sys(Error* err);

#define esys(__err__, __estr__, ...)	\
	_error(__err__, error_sys, __estr__, ##__VA_ARGS__);

#define error(__err__, __estr__, ...)	\
	_error(__err__, NULL, __estr__, ##__VA_ARGS__);

#define ewarn(__wstr__, ...)	\
	_warn(__func__, __wstr__, ##__VA_ARGS__);

#define einfo(__istr__, ...)	\
	_info(__func__, __istr__, ##__VA_ARGS__);

/*
 * Some useful types for unsigned
 * integer values.
 */
typedef uint64_t        u64;
typedef uint32_t        u32;
typedef uint16_t        u16;
typedef uint8_t         u8;

#endif
